<!--
  Author wln
  Version 1.0.0
  Date 2020年11月23日15:15:17
  Desc 表单组件 适用于简单的非行内表单
-->
<template>
	<el-form
			:model="model"
			:rules="rules"
			:label-width="labelWidth"
			:label-suffix="labelSuffix"
			:size="size"
			:disabled="disabled"
			:ref="elementName"
			class="bc-form"
	>
		<el-row :gutter="20">
			<el-col
					:span="twoColumns ? 12 : 24"
					v-for="item in element"
					v-show="!item.hidden"
					v-if="item.type != 'slot'"
			>
				<el-form-item
						:label="item.label"
						:prop="item.key"
				>

					<template v-if="item.type === 'input'">
						<el-input
								v-model="model[item.key]"
								:placeholder="'请输入' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'password'">
						<el-input
								show-password
								v-model="model[item.key]"
								:placeholder="'请输入' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'int'">
						<el-input
								v-model="model[item.key]"
								:placeholder="'请输入' + item.label"
								clearable
								@input="handleInput(item.key,item.type,item.negative || false)"
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'float'">
						<el-input
								v-model="model[item.key]"
								:placeholder="'请输入' + item.label"
								clearable
								@input="handleInput(item.key,item.type,item.negative || false)"
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'textarea'">
						<el-input
								type="textarea"
								:placeholder="'请输入' + item.label"
								v-model="model[item.key]"
								style="width: 100%;height: 100px"
								clearable
								:disabled="item.disabled || false"
								:maxlength = "item.maxlength || 200"
								:show-word-limit = "item.showWordLimit || false"
						/>
					</template>

					<template v-if="item.type === 'switch'">
						<el-switch
								v-model="model[item.key]"
								:active-color="item.activeColor || '#195ABE'"
								:inactive-color="item.inActiveColor || '#C0CCDA'"
								:active-value="item.activeValue || true "
								:inactive-value="item.inActiveValue || false "
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'select'">
						<el-select
								v-model="model[item.key]"
								:placeholder="'请选择' + item.label"
								filterable
								:multiple="item.multiple || false"
								clearable
								:disabled="item.disabled || false"
								v-if="item.list"
						>
							<el-option
									v-for="selectItem in item.list"
									:key="selectItem.value"
									:label="selectItem.label"
									:value="selectItem.value">
							</el-option>
						</el-select>
						<div v-else style="color: red">需传入list</div>
					</template>


					<template v-if="item.type === 'radio'">
						<el-radio-group
								v-model="model[item.key]"
								:disabled="item.disabled || false"
								v-if="item.list"
						>
							<el-radio :label="radioItem.value" v-for="radioItem in item.list">{{radioItem.label}}
							</el-radio>
						</el-radio-group>
						<div v-else style="color: red">需传入list</div>
					</template>

					<template v-if="item.type === 'checkbox'">
						<el-checkbox-group
								v-model="model[item.key]"
								:disabled="item.disabled || false"
								v-if="item.list"
						>
							<el-checkbox :label="checkItem.value" v-for="checkItem in item.list">{{checkItem.label}}
							</el-checkbox>
						</el-checkbox-group>
						<div v-else style="color: red">需传入list</div>
					</template>

					<template v-if="item.type === 'date'">
						<el-date-picker
								v-model="model[item.key]"
								type="date"
								format="yyyy-MM-dd"
								value-format="yyyy-MM-dd"
								:placeholder="'请选择' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'yearMonth'">
						<el-date-picker
								v-model="model[item.key]"
								type="month"
								format="yyyy-MM"
								value-format="yyyy-MM"
								:placeholder="'请选择' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'time'">
						<el-time-picker
								arrow-control
								v-model="model[item.key]"
								:placeholder="'请选择' + item.label"
								format="HH:mm:ss"
								value-format="HH:mm:ss"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'dateTime'">
						<el-date-picker
								arrow-control
								v-model="model[item.key]"
								type="datetime"
								format="yyyy-MM-dd HH:mm:ss"
								value-format="yyyy-MM-dd HH:mm:ss"
								:placeholder="'请选择' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'dateRange'">
						<el-date-picker
								v-model="model[item.key]"
								type="daterange"
								format="yyyy-MM-dd"
								value-format="yyyy-MM-dd"
								range-separator="至"
								start-placeholder="开始日期"
								end-placeholder="结束日期"
								:placeholder="'请选择' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'timeRange'">
						<el-time-picker
								is-range
								arrow-control
								v-model="model[item.key]"
								range-separator="至"
								start-placeholder="开始时间"
								end-placeholder="结束时间"
								:placeholder="'请选择' + item.label"
								format="HH:mm:ss"
								value-format="HH:mm:ss"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'dateTimeRange'">
						<el-date-picker
								arrow-control
								type="datetimerange"
								v-model="model[item.key]"
								range-separator="至"
								start-placeholder="开始日期"
								end-placeholder="结束日期"
								format="yyyy-MM-dd HH:mm:ss"
								value-format="yyyy-MM-dd HH:mm:ss"
								:placeholder="'请选择' + item.label"
								clearable
								:disabled="item.disabled || false"
						/>
					</template>

					<template v-if="item.type === 'cascader'">
						<el-cascader
								v-if="item.list"
								v-model="model[item.key]"
								:options="item.list"
								filterable
								clearable
								:disabled="item.disabled || false"
								expandTrigger="hover"
						/>
						<div v-else style="color: red">需传入list</div>
					</template>

					<template v-if="item.type === 'upload'">
						<div v-if="!item.uploadParams.uploadDiskPath" style="color: red">需要 “uploadDiskPath” 参数</div>
						<bc-upload
								v-else
								:type="item.uploadParams.type"
								:name-bind="item.uploadParams.nameBind"
								:path-bind="item.uploadParams.pathBind"
								:data-bind="model"
								:multiple="item.uploadParams.multiple || false"
								:file-can-click="item.uploadParams.fileCanClick || true"
								:upload-disk-path="item.uploadParams.uploadDiskPath"
								:max="item.uploadParams.max || 0"
								:accept="item.uploadParams.accept ? item.uploadParams.accept : ''"
								:disabled="disabled || item.disabled || false"
						/>
					</template>

				</el-form-item>
			</el-col>
		</el-row>
		<slot></slot>
	</el-form>
</template>

<script>
  import ruleValidate from '@/utils/bc-validate'
  import BcUpload from '@/components/BcUpload'

  export default {
    name: 'BcForm',
    components: {
      BcUpload
    },
    props: {
      element: {
        type: Array,
        default() {
          return []
        }
      },
      model: Object,
      labelWidth: {
        type: String,
        default: '80px'
      },
      labelSuffix: {
        type: String,
        default: ''
      },
      size: {
        type: String,
        default: 'small'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      elementName: String,
      twoColumns: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        rules: {}
      }
    },

    created() {
      this.dealRules()
      this.dealModelData()
    },

    methods: {
      // 处理表单数据
      dealModelData() {
        this.element.forEach(item => {
          if (item.type === 'select') {
            if (item.list) {
              return
            } else if (item.code) {
              return
            } else if (item.method) {
              return
            } else {
              this.$message(item.label + '参数错误')
            }
          }
        })
      },

      // 提交
      submit() {
        return new Promise(resolve => {
          this.$refs[this.elementName].validate(valid => {
            if (valid) {
              resolve(this.model)
            }
          })
        })
      },

      // 重置
      reset() {
        this.$refs[this.elementName].clearValidate()
      },

      // 输入数字
      handleInput(key, type, negative) {
        if (type == 'float') {
          if (negative) {
            this.model[key] = this.model[key].replace(/(?!^)\-|(?!^)[^\d\.]/g, '')
            this.model[key] = this.model[key].replace(/[^\d\-\.]/g, '')
          } else {
            this.model[key] = this.model[key].replace(/[^\d\.]/g, '')
          }
        } else if (type == 'int') {
          if (negative) {
            this.model[key] = this.model[key].replace(/(?!^)\-|(?!^)[^\d]/g, '')
            this.model[key] = this.model[key].replace(/[^\d\-]/g, '')
          } else {
            this.model[key] = this.model[key].replace(/[^\d]/g, '')
          }
        }
      },

      // 处理验证规则
      dealRules() {
        let obj = {}
        this.element.forEach(item => {
          let rule = []
          if (item.required) {
            let required = {
              required: true,
              trigger: ['blur', 'change']
            }
            rule.required = true
            if (item.type == 'input' || item.type == 'int' || item.type == 'float' || item.type == 'textarea') {
              required.message = item.message ? item.message : '请输入' + item.label
            } else {
              required.message = item.message ? item.message : '请选择' + item.label
            }
            rule.push(required)
          }
          if (item.rules) {
            let rules = {
              trigger: ['blur', 'change']
            }
            if (typeof item.rules === 'string') {
              switch (item.rules) {
                case 'phone':
                  rules.validator = ruleValidate.ruleValidator.validatePhone
                  break
                case 'telePhone':
                  rules.validator = ruleValidate.ruleValidator.validateTelPhone
                  break
                case 'idCard':
                  rules.validator = ruleValidate.ruleValidator.validateIdCard
                  break
                case 'email':
                  rules.validator = ruleValidate.ruleValidator.validateEmail
                  break
              }
            } else if (typeof item.rules === 'function') {
              rules.validator = item.rules
            }
            rule.push(rules)
          }
          if (item.required || item.rules) {
            obj[item.key] = rule
          }
        })
        this.rules = obj
        // created 调用  之后手动调用时  会触发验证 -> 此处取消验证
        this.$nextTick(() => {
          this.$refs[this.elementName].clearValidate()
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
	/deep/ .el-textarea {
		textarea {
			height: 100%;
		}
	}

	/deep/ .el-select {
		width: 100%;
	}

	.bc-form {
		padding: 0 20px;
	}

	/deep/ .el-date-editor {
		width: 100%;
	}

	/deep/ .el-cascader {
		width: 100%;
	}
</style>
